package com.zx.cloud.service;

import java.time.OffsetDateTime;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.google.common.base.Preconditions;
import com.zx.cloud.model.IdentityDomain;
import com.zx.cloud.persistence.CrudMapper;
import com.zx.cloud.util.Page;

/**
 * 支持泛型注入的CrudService的默认实现
 *
 * @author Alex
 */
public class CrudServiceImpl<T extends IdentityDomain> implements CrudService<T> {

    protected final CrudMapper<T> mapper;

    public CrudServiceImpl(CrudMapper<T> mapper) {
        this.mapper = mapper;
    }

    @Override
    public T get(Long id) {
        Preconditions.checkNotNull(id, "type of id should not be NULL");
        return mapper.get(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(T entity) {
        Preconditions.checkNotNull(entity, "persisting entity should not be NULL");
        initializeOffsetDateTime(entity);
        return mapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(T entity) {
        Preconditions.checkNotNull(entity, "entity in updating should not be NULL");
        entity.setUpdateTime(OffsetDateTime.now());
        return mapper.update(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(T entity) {
    	Preconditions.checkNotNull(entity, "entity in updating should not be NULL");
        Preconditions.checkNotNull(entity.getId(), "type of id should not be NULL");
        return mapper.remove(entity);
    }
    
    private void initializeOffsetDateTime(T entity) {
        entity.setCreateTime(OffsetDateTime.now());
        if (entity.getUpdateTime() == null) {
            entity.setUpdateTime(IdentityDomain.DEFAULT_DATE_TIME);
        }
        if (entity.getDeleteTime() == null) {
            entity.setDeleteTime(IdentityDomain.DEFAULT_DATE_TIME);
        }
    }

	@Override
	public List<T> find(T entity) {
		return mapper.find(entity);
	}

	@Override
	public long count(T entity) {
		return mapper.count(entity);
	}

	@Override
	public Page<T> page(T entity) {
		long count = mapper.count(entity);
		Page<T> page = new Page<T>(entity.getPageIndex_(),entity.getPageSize_());
		page.setData(mapper.find(entity));
		page.setTotalCount(count);
		return page;
	}

	@Override
	public T findOne(T entity) {
		entity.setLimitStart(0);
		entity.setLimitEnd(1);
		List<T> datas = mapper.find(entity);
		if (datas != null && datas.size() > 0) {
			return datas.get(0);
		}
		return null;
	}

}
